home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / mega99.zip / WEAPONS.QC < prev   
Text File  |  1996-08-04  |  33KB  |  1,489 lines

  1. /*
  2. */
  3. void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
  4. void () player_run;
  5. void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
  6. void(vector org, vector vel, float damage) SpawnBlood;
  7. void() SuperDamageSound;
  8. void(vector org, float spin) stuff_fly;
  9. void(vector org, vector dir) launch_spike;
  10. void() W_FireSuperSpikes;
  11. void() BecomeExplosion;
  12. void() T_MissileTouch;
  13. void() spike_touch;
  14. // called by worldspawn
  15. void() W_Precache =
  16. {
  17.     precache_sound ("weapons/r_exp3.wav");    // new rocket explosion
  18.     precache_sound ("weapons/rocket1i.wav");    // spike gun
  19.     precache_sound ("weapons/sgun1.wav");
  20.     precache_sound ("weapons/guncock.wav");    // player shotgun
  21.     precache_sound ("weapons/ric1.wav");    // ricochet (used in c code)
  22.     precache_sound ("weapons/ric2.wav");    // ricochet (used in c code)
  23.     precache_sound ("weapons/ric3.wav");    // ricochet (used in c code)
  24.     precache_sound ("weapons/spike2.wav");    // super spikes
  25.     precache_sound ("weapons/tink1.wav");    // spikes tink (used in c code)
  26.     precache_sound ("weapons/grenade.wav");    // grenade launcher
  27.     precache_sound ("weapons/bounce.wav");        // grenade bounce
  28.     precache_sound ("weapons/shotgn2.wav");    // super shotgun
  29.     precache_model2 ("progs/laser.mdl");
  30.     precache_sound2 ("enforcer/enfire.wav");
  31.     precache_sound2 ("enforcer/enfstop.wav");
  32.         precache_model2 ("progs/k_spike.mdl");
  33.         precache_sound2 ("hknight/attack1.wav");
  34. };
  35. void(vector org, vector dir) Flare=
  36. {
  37.  
  38.     local    entity missile, mpuff;
  39.     
  40.         if(self.ammo_nails < 5)
  41.         {
  42.                 dprint("Not Enough Ammo for flair\n");
  43.                 return;
  44.         }
  45.  
  46.  
  47.         self.currentammo = self.ammo_nails = self.ammo_nails - 5;
  48.         sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_NORM);
  49.         missile = spawn ();
  50.     missile.owner = self;
  51.     missile.movetype = MOVETYPE_FLYMISSILE;
  52.     missile.solid = SOLID_BBOX;
  53.         missile.effects = EF_DIMLIGHT;
  54.  
  55. // set missile speed    
  56.  
  57.     makevectors (self.v_angle);
  58.     missile.velocity = aim(self, 1000);
  59.         missile.velocity = missile.velocity * 0;
  60.     missile.angles = vectoangles(missile.velocity);
  61.     
  62.         missile.touch = spike_touch; //T_MissileTouch;
  63.     
  64. // set missile duration
  65.         missile.nextthink = time + 15;
  66.     missile.think = SUB_Remove;
  67.  
  68.         setmodel (missile, "progs/laser.mdl");
  69.     setsize (missile, '0 0 0', '0 0 0');        
  70.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  71.  
  72.         
  73. };
  74.  
  75.  
  76. void() BigBoom =
  77. {
  78.     local float    damg;
  79.  
  80.     if (other == self.owner)
  81.         return;        // don't explode on owner
  82.  
  83.     if (pointcontents(self.origin) == CONTENT_SKY)
  84.     {
  85.         remove(self);
  86.         return;
  87.     }
  88.  
  89.         damg = 200 + random()*20;
  90.     
  91.     if (other.health)
  92.     {
  93.         if (other.classname == "monster_shambler")
  94.                         damg = damg * 4.5;      // mostly immune
  95.         T_Damage (other, self, self.owner, damg );
  96.     }
  97.  
  98.     // don't do radius damage to the other, because all the damage
  99.     // was done in the impact
  100.         T_RadiusDamage (self, self.owner, 500, other);
  101.  
  102. //    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  103.     self.origin = self.origin - 8*normalize(self.velocity);
  104.  
  105.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  106.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  107.     WriteCoord (MSG_BROADCAST, self.origin_x);
  108.     WriteCoord (MSG_BROADCAST, self.origin_y);
  109.     WriteCoord (MSG_BROADCAST, self.origin_z);
  110.  
  111.     BecomeExplosion ();
  112. };
  113.  
  114.  
  115.  
  116.  
  117.  
  118. void() Touch_Laser =
  119. {
  120.     local float    damg;
  121.  
  122.     if (other == self.owner)
  123.         return;        // don't explode on owner
  124.  
  125.     if (pointcontents(self.origin) == CONTENT_SKY)
  126.     {
  127.         remove(self);
  128.         return;
  129.     }
  130.  
  131.         damg = 50 + random()*20;
  132.     
  133.     if (other.health)
  134.     {
  135.         if (other.classname == "monster_shambler")
  136.                         damg = damg * 3.0;      // mostly immune
  137.         T_Damage (other, self, self.owner, damg );
  138.     }
  139.  
  140.     // don't do radius damage to the other, because all the damage
  141.     // was done in the impact
  142.         T_RadiusDamage (self, self.owner, 50, other);
  143.  
  144. //    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  145.     self.origin = self.origin - 8*normalize(self.velocity);
  146.  
  147.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  148.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  149.     WriteCoord (MSG_BROADCAST, self.origin_x);
  150.     WriteCoord (MSG_BROADCAST, self.origin_y);
  151.     WriteCoord (MSG_BROADCAST, self.origin_z);
  152.  
  153.     BecomeExplosion ();
  154.         
  155. };
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162. void(vector org, vector dir) Laser =
  163. {
  164.     newmis = spawn ();
  165.     newmis.owner = self;
  166.         newmis.movetype = MOVETYPE_FLY;
  167.     newmis.solid = SOLID_BBOX;
  168.     newmis.effects = EF_DIMLIGHT;
  169.         newmis.classname = "knightspike";
  170.     setmodel (newmis, "progs/k_spike.mdl");
  171.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  172.         newmis.angles = vectoangles(dir);
  173.         newmis.touch = Touch_Laser;
  174.     newmis.think = SUB_Remove;
  175.     newmis.nextthink = time + 6;
  176.     setorigin (newmis, org);
  177.         sound (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM);
  178.         newmis.velocity = dir * 500;
  179. };
  180.  
  181.  
  182.  
  183.  
  184.  
  185. float() crandom =
  186. {
  187.     return 2*(random() - 0.5);
  188. };
  189.  
  190. /*
  191. ================
  192. W_FireAxe
  193. ================
  194. */
  195. void(float ox) W_FireAxe =
  196. {
  197.     local vector    dir;
  198.     local entity    old;
  199.  
  200.     local    vector    source;
  201.     local    vector    org;
  202.  
  203.     makevectors (self.v_angle);
  204.     
  205.     if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
  206.     {
  207.         W_FireSuperSpikes ();
  208.         return;
  209.     }
  210.  
  211.     if (self.ammo_nails < 1)
  212.     {
  213.                 /*self.weapon = W_BestWeapon ();
  214.         W_SetCurrentAmmo ();
  215.                 return;*/
  216.     source = self.origin + '0 0 16';
  217.     traceline (source, source + v_forward*64, FALSE, self);
  218.     if (trace_fraction == 1.0)
  219.         return;
  220.     
  221.     org = trace_endpos - v_forward*4;
  222.  
  223.     if (trace_ent.takedamage)
  224.     {
  225.         trace_ent.axhitme = 1;
  226.         SpawnBlood (org, '0 0 0', 20);
  227.         T_Damage (trace_ent, self, self, 20);
  228.     }
  229.     else
  230.     {    // hit wall
  231.         sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
  232.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  233.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  234.         WriteCoord (MSG_BROADCAST, org_x);
  235.         WriteCoord (MSG_BROADCAST, org_y);
  236.         WriteCoord (MSG_BROADCAST, org_z);
  237.     }
  238.         
  239.     }
  240.         else
  241.         {
  242.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  243.     self.attack_finished = time + 0.2;
  244.     self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  245.     dir = aim (self, 1000);
  246.         /*launch_spike*/ Laser (self.origin + '0 0 16' + v_right*ox, dir);
  247.  
  248.     self.punchangle_x = -2;
  249.         }
  250. };
  251.  
  252.  
  253. //============================================================================
  254.  
  255.  
  256. vector() wall_velocity =
  257. {
  258.     local vector    vel;
  259.     
  260.     vel = normalize (self.velocity);
  261.     vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5));
  262.     vel = vel + 2*trace_plane_normal;
  263.     vel = vel * 200;
  264.     
  265.     return vel;
  266. };
  267.  
  268.  
  269. /*
  270. ================
  271. SpawnMeatSpray
  272. ================
  273. */
  274. void(vector org, vector vel) SpawnMeatSpray =
  275. {
  276.     local    entity missile, mpuff;
  277.     local    vector    org;
  278.  
  279.     missile = spawn ();
  280.     missile.owner = self;
  281.     missile.movetype = MOVETYPE_BOUNCE;
  282.     missile.solid = SOLID_NOT;
  283.  
  284.     makevectors (self.angles);
  285.  
  286.         missile.velocity = vel*10;
  287.     missile.velocity_z = missile.velocity_z + 250 + 50*random();
  288.  
  289.     missile.avelocity = '3000 1000 2000';
  290.     
  291. // set missile duration
  292.     missile.nextthink = time + 1;
  293.     missile.think = SUB_Remove;
  294.  
  295.     setmodel (missile, "progs/zom_gib.mdl");
  296.     setsize (missile, '0 0 0', '0 0 0');        
  297.     setorigin (missile, org);
  298. };
  299.  
  300. /*
  301. ================
  302. SpawnBlood
  303. ================
  304. */
  305. void(vector org, vector vel, float damage) SpawnBlood =
  306. {
  307.     particle (org, vel*0.1, 73, damage*2);
  308. };
  309.  
  310. /*
  311. ================
  312. spawn_touchblood
  313. ================
  314. */
  315. void(float damage) spawn_touchblood =
  316. {
  317.     local vector    vel;
  318.  
  319.     vel = wall_velocity () * 0.2;
  320.     SpawnBlood (self.origin + vel*0.01, vel, damage);
  321. };
  322.  
  323.  
  324. /*
  325. ================
  326. SpawnChunk
  327. ================
  328. */
  329. void(vector org, vector vel) SpawnChunk =
  330. {
  331.     particle (org, vel*0.02, 0, 10);
  332. };
  333.  
  334. /*
  335. ==============================================================================
  336.  
  337. MULTI-DAMAGE
  338.  
  339. Collects multiple small damages into a single damage
  340.  
  341. ==============================================================================
  342. */
  343.  
  344. entity    multi_ent;
  345. float    multi_damage;
  346.  
  347. void() ClearMultiDamage =
  348. {
  349.     multi_ent = world;
  350.     multi_damage = 0;
  351. };
  352.  
  353. void() ApplyMultiDamage =
  354. {
  355.     if (!multi_ent)
  356.         return;
  357.     T_Damage (multi_ent, self, self, multi_damage);
  358. };
  359.  
  360. void(entity hit, float damage) AddMultiDamage =
  361. {
  362.     if (!hit)
  363.         return;
  364.     
  365.     if (hit != multi_ent)
  366.     {
  367.         ApplyMultiDamage ();
  368.         multi_damage = damage;
  369.         multi_ent = hit;
  370.     }
  371.     else
  372.         multi_damage = multi_damage + damage;
  373. };
  374.  
  375. /*
  376. ==============================================================================
  377.  
  378. BULLETS
  379.  
  380. ==============================================================================
  381. */
  382.  
  383. /*
  384. ================
  385. TraceAttack
  386. ================
  387. */
  388. void(float damage, vector dir) TraceAttack =
  389. {
  390.     local    vector    vel, org;
  391.     
  392.     vel = normalize(dir + v_up*crandom() + v_right*crandom());
  393.     vel = vel + 2*trace_plane_normal;
  394.     vel = vel * 200;
  395.  
  396.     org = trace_endpos - dir*4;
  397.  
  398.     if (trace_ent.takedamage)
  399.     {
  400.         SpawnBlood (org, vel*0.2, damage);
  401.         AddMultiDamage (trace_ent, damage);
  402.     }
  403.     else
  404.     {
  405.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  406.         WriteByte (MSG_BROADCAST, TE_GUNSHOT);
  407.         WriteCoord (MSG_BROADCAST, org_x);
  408.         WriteCoord (MSG_BROADCAST, org_y);
  409.         WriteCoord (MSG_BROADCAST, org_z);
  410.     }
  411. };
  412.  
  413. /*
  414. ================
  415. FireBullets
  416.  
  417. Used by shotgun, super shotgun, and enemy soldier firing
  418. Go to the trouble of combining multiple pellets into a single damage call.
  419. ================
  420. */
  421. void(float shotcount, vector dir, vector spread) FireBullets =
  422. {
  423.     local    vector direction;
  424.     local    vector    src;
  425.     
  426.     makevectors(self.v_angle);
  427.  
  428.     src = self.origin + v_forward*10;
  429.     src_z = self.absmin_z + self.size_z * 0.7;
  430.  
  431.     ClearMultiDamage ();
  432.     while (shotcount > 0)
  433.     {
  434.         direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up;
  435.  
  436.         traceline (src, src + direction*2048, FALSE, self);
  437.         if (trace_fraction != 1.0)
  438.             TraceAttack (4, direction);
  439.  
  440.         shotcount = shotcount - 1;
  441.     }
  442.     ApplyMultiDamage ();
  443. };
  444.  
  445. /*
  446. ================
  447. W_FireShotgun
  448. ================
  449. */
  450. void() W_FireShotgun =
  451. {
  452.     local vector dir;
  453.  
  454.     sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);    
  455.  
  456.     self.punchangle_x = -2;
  457.     
  458.     self.currentammo = self.ammo_shells = self.ammo_shells - 1;
  459.     dir = aim (self, 100000);
  460.         FireBullets (10, dir, '0.00 0.00 0');
  461. };
  462.  
  463.  
  464. /*
  465. ================
  466. W_FireSuperShotgun
  467. ================
  468. */
  469. void() W_FireSuperShotgun =
  470. {
  471.     local vector dir;
  472.  
  473.     if (self.currentammo == 1)
  474.     {
  475.         W_FireShotgun ();
  476.         return;
  477.     }
  478.         
  479.     sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);    
  480.  
  481.     self.punchangle_x = -4;
  482.     
  483.     self.currentammo = self.ammo_shells = self.ammo_shells - 2;
  484.     dir = aim (self, 100000);
  485.         FireBullets (20, dir, '0.14 0.08 0');
  486. };
  487.  
  488.  
  489. /*
  490. ==============================================================================
  491.  
  492. ROCKETS
  493.  
  494. ==============================================================================
  495. */
  496.  
  497. void()    s_explode1    =    [0,        s_explode2] {};
  498. void()    s_explode2    =    [1,        s_explode3] {};
  499. void()    s_explode3    =    [2,        s_explode4] {};
  500. void()    s_explode4    =    [3,        s_explode5] {};
  501. void()    s_explode5    =    [4,        s_explode6] {};
  502. void()    s_explode6    =    [5,        SUB_Remove] {};
  503.  
  504. void() BecomeExplosion =
  505. {
  506.     self.movetype = MOVETYPE_NONE;
  507.     self.velocity = '0 0 0';
  508.         self.touch = SUB_Null;
  509.     setmodel (self, "progs/s_explod.spr");
  510.     self.solid = SOLID_NOT;
  511.         s_explode1 ();
  512. };
  513.  
  514. void() T_MissileTouch =
  515. {
  516.     local float    damg;
  517.  
  518.     if (other == self.owner)
  519.         return;        // don't explode on owner
  520.  
  521.     if (pointcontents(self.origin) == CONTENT_SKY)
  522.     {
  523.         remove(self);
  524.         return;
  525.     }
  526.  
  527.         damg = 400 + random()*20;
  528.     
  529.     if (other.health)
  530.     {
  531.         if (other.classname == "monster_shambler")
  532.             damg = damg * 0.5;    // mostly immune
  533.         T_Damage (other, self, self.owner, damg );
  534.     }
  535.  
  536.     // don't do radius damage to the other, because all the damage
  537.     // was done in the impact
  538.         T_RadiusDamage (self, self.owner, 100, other);
  539.  
  540. //    sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM);
  541.     self.origin = self.origin - 8*normalize(self.velocity);
  542.  
  543.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  544.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  545.     WriteCoord (MSG_BROADCAST, self.origin_x);
  546.     WriteCoord (MSG_BROADCAST, self.origin_y);
  547.     WriteCoord (MSG_BROADCAST, self.origin_z);
  548.  
  549.     BecomeExplosion ();
  550. };
  551.  
  552.  
  553.  
  554. /*
  555. ================
  556. W_FireRocket
  557. ================
  558. */
  559. void() W_FireRocket =
  560. {
  561.     local    entity missile, mpuff;
  562.     
  563.     self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
  564.     
  565.     sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
  566.  
  567.     self.punchangle_x = -2;
  568.  
  569.     missile = spawn ();
  570.     missile.owner = self;
  571.     missile.movetype = MOVETYPE_FLYMISSILE;
  572.     missile.solid = SOLID_BBOX;
  573.         
  574. // set missile speed    
  575.  
  576.     makevectors (self.v_angle);
  577.     missile.velocity = aim(self, 1000);
  578.         missile.velocity = missile.velocity * 700;
  579.     missile.angles = vectoangles(missile.velocity);
  580.     
  581.     missile.touch = T_MissileTouch;
  582.     
  583. // set missile duration
  584.         missile.nextthink = time + 600;
  585.     missile.think = SUB_Remove;
  586.  
  587.     setmodel (missile, "progs/missile.mdl");
  588.     setsize (missile, '0 0 0', '0 0 0');        
  589.     setorigin (missile, self.origin + v_forward*8 + '0 0 16');
  590. };
  591.  
  592. /*
  593. ===============================================================================
  594.  
  595. LIGHTNING
  596.  
  597. ===============================================================================
  598. */
  599.  
  600. /*
  601. =================
  602. LightningDamage
  603. =================
  604. */
  605. void(vector p1, vector p2, entity from, float damage) LightningDamage =
  606. {
  607.     local entity        e1, e2;
  608.     local vector        f;
  609.     
  610.     f = p2 - p1;
  611.     normalize (f);
  612.     f_x = 0 - f_y;
  613.     f_y = f_x;
  614.     f_z = 0;
  615.     f = f*16;
  616.  
  617.     e1 = e2 = world;
  618.  
  619.     traceline (p1, p2, FALSE, self);
  620.     if (trace_ent.takedamage)
  621.     {
  622.         particle (trace_endpos, '0 0 100', 225, damage*4);
  623.         T_Damage (trace_ent, from, from, damage);
  624.         if (self.classname == "player")
  625.         {
  626.             if (other.classname == "player")
  627.                 trace_ent.velocity_z = trace_ent.velocity_z + 400;
  628.         }
  629.     }
  630.     e1 = trace_ent;
  631.  
  632.     traceline (p1 + f, p2 + f, FALSE, self);
  633.     if (trace_ent != e1 && trace_ent.takedamage)
  634.     {
  635.         particle (trace_endpos, '0 0 100', 225, damage*4);
  636.         T_Damage (trace_ent, from, from, damage);
  637.     }
  638.     e2 = trace_ent;
  639.  
  640.     traceline (p1 - f, p2 - f, FALSE, self);
  641.     if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
  642.     {
  643.         particle (trace_endpos, '0 0 100', 225, damage*4);
  644.         T_Damage (trace_ent, from, from, damage);
  645.     }
  646. };
  647.  
  648.  
  649. void() W_FireLightning =
  650. {
  651.     local    vector        org;
  652.  
  653.     if (self.ammo_cells < 1)
  654.     {
  655.         self.weapon = W_BestWeapon ();
  656.         W_SetCurrentAmmo ();
  657.         return;
  658.     }
  659.  
  660. // explode if under water
  661.     if (self.waterlevel > 1)
  662.     {
  663.         T_RadiusDamage (self, self, 35*self.ammo_cells, world);
  664.         self.ammo_cells = 0;
  665.         W_SetCurrentAmmo ();
  666.         return;
  667.     }
  668.  
  669.     if (self.t_width < time)
  670.     {
  671.         sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
  672.         self.t_width = time + 0.6;
  673.     }
  674.     self.punchangle_x = -2;
  675.  
  676.     self.currentammo = self.ammo_cells = self.ammo_cells - 1;
  677.  
  678.     org = self.origin + '0 0 16';
  679.     
  680.     traceline (org, org + v_forward*600, TRUE, self);
  681.  
  682.     WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  683.     WriteByte (MSG_BROADCAST, TE_LIGHTNING2);
  684.     WriteEntity (MSG_BROADCAST, self);
  685.     WriteCoord (MSG_BROADCAST, org_x);
  686.     WriteCoord (MSG_BROADCAST, org_y);
  687.     WriteCoord (MSG_BROADCAST, org_z);
  688.     WriteCoord (MSG_BROADCAST, trace_endpos_x);
  689.     WriteCoord (MSG_BROADCAST, trace_endpos_y);
  690.     WriteCoord (MSG_BROADCAST, trace_endpos_z);
  691.  
  692.     LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30);
  693. };
  694.  
  695.  
  696. //=============================================================================
  697.  
  698.  
  699. void() GrenadeExplode =
  700. {
  701.         T_RadiusDamage (self, self.owner, 0, world);
  702.  
  703.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  704.     WriteByte (MSG_BROADCAST, TE_EXPLOSION);
  705.     WriteCoord (MSG_BROADCAST, self.origin_x);
  706.     WriteCoord (MSG_BROADCAST, self.origin_y);
  707.     WriteCoord (MSG_BROADCAST, self.origin_z);
  708.  
  709.         self.solid=SOLID_NOT;
  710.         BecomeExplosion ();
  711.  
  712.         stuff_fly(self.origin + '0 0 -1', 0);
  713.         stuff_fly(self.origin + '0 0 -1', 1);
  714.         stuff_fly(self.origin + '0 0 -1', 2);
  715.         stuff_fly(self.origin + '0 0 -1', 3);
  716.         stuff_fly(self.origin + '0 0 -1', 4);
  717.  
  718.                 
  719. };
  720.  
  721. void() GoUp=
  722. {
  723.         local entity missile, mpuff;
  724.  
  725.         self.movetype=MOVETYPE_NONE;
  726.         self.velocity='0 0 0';
  727.         //setmodel (self, "progs/s_explod.spr");
  728.         //s_explode1;
  729.         self.nextthink=time + 0;
  730.         self.think = SUB_Remove;
  731.  
  732.         missile=spawn ();
  733.         missile.owner=self;
  734.         missile.movetype=MOVETYPE_BOUNCE;
  735.         missile.solid=SOLID_BBOX;
  736.         missile.classname="grenade";
  737.         missile.velocity='0 0 650';
  738.         missile.angles=vectoangles(missile.velocity);
  739.         missile.touch=GrenadeExplode;
  740.         missile.nextthink=time+1;
  741.         missile.think=GrenadeExplode;
  742.         setmodel (missile, "progs/missile.mdl");
  743.         setsize (missile, '0 0 0', '0 0 0');
  744.         setorigin (missile, self.origin);
  745.  
  746. };
  747.  
  748. void() GrenadeTouch =
  749. {
  750.     if (other == self.owner)
  751.         return;        // don't explode on owner
  752.     if (other.takedamage == DAMAGE_AIM)
  753.     {
  754.                 T_MissileTouch ();
  755.         return;
  756.     }
  757.     sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);    // bounce sound
  758.     if (self.velocity == '0 0 0')
  759.         self.avelocity = '0 0 0';
  760. };
  761.  
  762. /*
  763. ================
  764. W_FireGrenade
  765. ================
  766. */
  767. void() W_FireGrenade =
  768. {
  769.     local    entity missile, mpuff;
  770.     
  771.         self.currentammo = self.ammo_rockets = self.ammo_rockets - 7;
  772.     
  773.     sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
  774.  
  775.     self.punchangle_x = -2;
  776.  
  777.     missile = spawn ();
  778.     missile.owner = self;
  779.     missile.movetype = MOVETYPE_BOUNCE;
  780.     missile.solid = SOLID_BBOX;
  781.     missile.classname = "grenade";
  782.         
  783. // set missile speed    
  784.  
  785.     makevectors (self.v_angle);
  786.  
  787.     if (self.v_angle_x)
  788.         missile.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
  789.     else
  790.     {
  791.         missile.velocity = aim(self, 10000);
  792.         missile.velocity = missile.velocity * 600;
  793.         missile.velocity_z = 200;
  794.     }
  795.  
  796.     missile.avelocity = '300 300 300';
  797.  
  798.     missile.angles = vectoangles(missile.velocity);
  799.     
  800.     missile.touch = GrenadeTouch;
  801.     
  802. // set missile duration
  803.     missile.nextthink = time + 2.5;
  804.         missile.think = GoUp;
  805.  
  806.     setmodel (missile, "progs/grenade.mdl");
  807.     setsize (missile, '0 0 0', '0 0 0');        
  808.     setorigin (missile, self.origin);
  809.  
  810. };
  811.  
  812.  
  813. //=============================================================================
  814.  
  815. void() spike_touch;
  816. void() superspike_touch;
  817.  
  818.  
  819. /*
  820. ===============
  821. launch_spike
  822.  
  823. Used for both the player and the ogre
  824. ===============
  825. */
  826. void(vector org, vector dir) launch_spike =
  827. {        
  828.     newmis = spawn ();
  829.     newmis.owner = self;
  830.         //newmis.movetype = MOVETYPE_FLYMISSILE;
  831.         //newmis.solid = SOLID_BBOX;
  832.  
  833.  
  834.     newmis.movetype = MOVETYPE_FLY;
  835.     newmis.solid = SOLID_BBOX;
  836.     newmis.effects = EF_DIMLIGHT;
  837.  
  838.     setmodel (newmis, "progs/laser.mdl");
  839.     setsize (newmis, '0 0 0', '0 0 0');        
  840.         newmis.angles = vectoangles(dir);
  841.         newmis.touch = spike_touch;
  842.     newmis.classname = "spike";
  843.     newmis.think = SUB_Remove;
  844.     newmis.nextthink = time + 6;
  845.         //setmodel (newmis, "progs/spike.mdl");
  846.         //setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  847.     setorigin (newmis, org);
  848.         sound (self, CHAN_WEAPON, "enforcer/enfire.wav", 1, ATTN_NORM);
  849.         newmis.velocity = dir * 500;
  850. };
  851.  
  852. void() W_FireSuperSpikes =
  853. {
  854.     local vector    dir;
  855.     local entity    old;
  856.     
  857.         sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
  858.         self.attack_finished = time + 0.5;
  859.     self.currentammo = self.ammo_nails = self.ammo_nails - 2;
  860.     dir = aim (self, 1000);
  861.     launch_spike (self.origin + '0 0 16', dir);
  862.     newmis.touch = superspike_touch;
  863.         setmodel (newmis, "progs/laser.mdl");
  864.     setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);        
  865.     self.punchangle_x = -2;
  866. };
  867.  
  868. void(float ox) W_FireSpikes =
  869. {
  870.     local vector    dir;
  871.     local entity    old;
  872.     
  873.     makevectors (self.v_angle);
  874.     
  875.     if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
  876.     {
  877.         W_FireSuperSpikes ();
  878.         return;
  879.     }
  880.  
  881.     if (self.ammo_nails < 1)
  882.     {
  883.         self.weapon = W_BestWeapon ();
  884.         W_SetCurrentAmmo ();
  885.         return;
  886.     }
  887.  
  888.     sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
  889.     self.attack_finished = time + 0.2;
  890.     self.currentammo = self.ammo_nails = self.ammo_nails - 1;
  891.     dir = aim (self, 1000);
  892.     launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
  893.  
  894.     self.punchangle_x = -2;
  895. };
  896.  
  897.  
  898.  
  899. .float hit_z;
  900. void() spike_touch =
  901. {
  902. local float rand;
  903.     if (other == self.owner)
  904.         return;
  905.  
  906.     if (other.solid == SOLID_TRIGGER)
  907.         return;    // trigger field, do nothing
  908.  
  909.     if (pointcontents(self.origin) == CONTENT_SKY)
  910.     {
  911.         remove(self);
  912.         return;
  913.     }
  914.     
  915. // hit something that bleeds
  916.     if (other.takedamage)
  917.     {
  918.         spawn_touchblood (9);
  919.                 T_Damage (other, self, self.owner, 20);
  920.     }
  921.     else
  922.     {
  923.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  924.         
  925.         if (self.classname == "wizspike")
  926.             WriteByte (MSG_BROADCAST, TE_WIZSPIKE);
  927.         else if (self.classname == "knightspike")
  928.             WriteByte (MSG_BROADCAST, TE_KNIGHTSPIKE);
  929.         else
  930.             WriteByte (MSG_BROADCAST, TE_SPIKE);
  931.         WriteCoord (MSG_BROADCAST, self.origin_x);
  932.         WriteCoord (MSG_BROADCAST, self.origin_y);
  933.         WriteCoord (MSG_BROADCAST, self.origin_z);
  934.     }
  935.  
  936.     remove(self);
  937.  
  938. };
  939.  
  940. void() superspike_touch =
  941. {
  942. local float rand;
  943.     if (other == self.owner)
  944.         return;
  945.  
  946.     if (other.solid == SOLID_TRIGGER)
  947.         return;    // trigger field, do nothing
  948.  
  949.     if (pointcontents(self.origin) == CONTENT_SKY)
  950.     {
  951.         remove(self);
  952.         return;
  953.     }
  954.     
  955. // hit something that bleeds
  956.     if (other.takedamage)
  957.     {
  958.         spawn_touchblood (18);
  959.                 T_Damage (other, self, self.owner, 30);
  960.     }
  961.     else
  962.     {
  963.         WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
  964.         WriteByte (MSG_BROADCAST, TE_SUPERSPIKE);
  965.         WriteCoord (MSG_BROADCAST, self.origin_x);
  966.         WriteCoord (MSG_BROADCAST, self.origin_y);
  967.         WriteCoord (MSG_BROADCAST, self.origin_z);
  968.     }
  969.  
  970.     remove(self);
  971.  
  972. };
  973.  
  974.  
  975. /*
  976. ===============================================================================
  977.  
  978. PLAYER WEAPON USE
  979.  
  980. ===============================================================================
  981. */
  982.  
  983. void() W_SetCurrentAmmo =
  984. {
  985.     player_run ();        // get out of any weapon firing states
  986.  
  987.     self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) );
  988.     
  989.     if (self.weapon == IT_AXE)
  990.     {
  991.         self.currentammo = 0;
  992.         self.weaponmodel = "progs/v_axe.mdl";
  993.         self.weaponframe = 0;
  994.         self.items = self.items | IT_NAILS;
  995.                 
  996.         }
  997.     else if (self.weapon == IT_SHOTGUN)
  998.     {
  999.         self.currentammo = self.ammo_shells;
  1000.         self.weaponmodel = "progs/v_shot.mdl";
  1001.         self.weaponframe = 0;
  1002.         self.items = self.items | IT_SHELLS;
  1003.     }
  1004.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1005.     {
  1006.         self.currentammo = self.ammo_shells;
  1007.         self.weaponmodel = "progs/v_shot2.mdl";
  1008.         self.weaponframe = 0;
  1009.         self.items = self.items | IT_SHELLS;
  1010.     }
  1011.     else if (self.weapon == IT_NAILGUN)
  1012.     {
  1013.         self.currentammo = self.ammo_nails;
  1014.         self.weaponmodel = "progs/v_nail.mdl";
  1015.         self.weaponframe = 0;
  1016.         self.items = self.items | IT_NAILS;
  1017.     }
  1018.     else if (self.weapon == IT_SUPER_NAILGUN)
  1019.     {
  1020.         self.currentammo = self.ammo_nails;
  1021.         self.weaponmodel = "progs/v_nail2.mdl";
  1022.         self.weaponframe = 0;
  1023.         self.items = self.items | IT_NAILS;
  1024.     }
  1025.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  1026.     {
  1027.         self.currentammo = self.ammo_rockets;
  1028.         self.weaponmodel = "progs/v_rock.mdl";
  1029.         self.weaponframe = 0;
  1030.         self.items = self.items | IT_ROCKETS;
  1031.     }
  1032.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1033.     {
  1034.         self.currentammo = self.ammo_rockets;
  1035.         self.weaponmodel = "progs/v_rock2.mdl";
  1036.         self.weaponframe = 0;
  1037.         self.items = self.items | IT_ROCKETS;
  1038.     }
  1039.     else if (self.weapon == IT_LIGHTNING)
  1040.     {
  1041.         self.currentammo = self.ammo_cells;
  1042.         self.weaponmodel = "progs/v_light.mdl";
  1043.         self.weaponframe = 0;
  1044.         self.items = self.items | IT_CELLS;
  1045.     }
  1046.     else
  1047.     {
  1048.         self.currentammo = 0;
  1049.         self.weaponmodel = "";
  1050.         self.weaponframe = 0;
  1051.     }
  1052. };
  1053.  
  1054. float() W_BestWeapon =
  1055. {
  1056.     local    float    it;
  1057.     
  1058.     it = self.items;
  1059.  
  1060.     if(self.ammo_cells >= 1 && (it & IT_LIGHTNING) )
  1061.         return IT_LIGHTNING;
  1062.     else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) )
  1063.         return IT_SUPER_NAILGUN;
  1064.     else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) )
  1065.         return IT_SUPER_SHOTGUN;
  1066.     else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) )
  1067.         return IT_NAILGUN;
  1068.     else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) )
  1069.         return IT_SHOTGUN;
  1070.         
  1071. /*
  1072.     if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) )
  1073.         return IT_ROCKET_LAUNCHER;
  1074.     else if(self.ammo_rockets >= 1 && (it & IT_GRENADE_LAUNCHER) )
  1075.         return IT_GRENADE_LAUNCHER;
  1076.  
  1077. */
  1078.  
  1079.     return IT_AXE;
  1080. };
  1081.  
  1082. float() W_CheckNoAmmo =
  1083. {
  1084.     if (self.currentammo > 0)
  1085.         return TRUE;
  1086.  
  1087.     if (self.weapon == IT_AXE)
  1088.         return TRUE;
  1089.     
  1090.     self.weapon = W_BestWeapon ();
  1091.  
  1092.     W_SetCurrentAmmo ();
  1093.     
  1094. // drop the weapon down
  1095.     return FALSE;
  1096. };
  1097.  
  1098. /*
  1099. ============
  1100. W_Attack
  1101.  
  1102. An attack impulse can be triggered now
  1103. ============
  1104. */
  1105. void()    player_axe1;
  1106. void()    player_axeb1;
  1107. void()    player_axec1;
  1108. void()    player_axed1;
  1109. void()    player_shot1;
  1110. void()    player_nail1;
  1111. void()    player_light1;
  1112. void()    player_rocket1;
  1113.  
  1114. void() W_Attack =
  1115. {
  1116.     local    float    r;
  1117.  
  1118.     if (!W_CheckNoAmmo ())
  1119.         return;
  1120.  
  1121.     makevectors    (self.v_angle);            // calculate forward angle for velocity
  1122.     self.show_hostile = time + 1;    // wake monsters up
  1123.  
  1124.     if (self.weapon == IT_AXE)
  1125.     {
  1126.         sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
  1127.         r = random();
  1128.         if (r < 0.25)
  1129.             player_axe1 ();
  1130.         else if (r<0.5)
  1131.             player_axeb1 ();
  1132.         else if (r<0.75)
  1133.             player_axec1 ();
  1134.         else
  1135.             player_axed1 ();
  1136.         self.attack_finished = time + 0.5;
  1137.     }
  1138.     else if (self.weapon == IT_SHOTGUN)
  1139.     {
  1140.         player_shot1 ();
  1141.         W_FireShotgun ();
  1142.         self.attack_finished = time + 0.5;
  1143.     }
  1144.     else if (self.weapon == IT_SUPER_SHOTGUN)
  1145.     {
  1146.         player_shot1 ();
  1147.         W_FireSuperShotgun ();
  1148.         self.attack_finished = time + 0.7;
  1149.     }
  1150.     else if (self.weapon == IT_NAILGUN)
  1151.     {
  1152.         player_nail1 ();
  1153.     }
  1154.     else if (self.weapon == IT_SUPER_NAILGUN)
  1155.     {
  1156.         player_nail1 ();
  1157.     }
  1158.     else if (self.weapon == IT_GRENADE_LAUNCHER)
  1159.     {
  1160.         player_rocket1();
  1161.         W_FireGrenade();
  1162.         self.attack_finished = time + 0.6;
  1163.     }
  1164.     else if (self.weapon == IT_ROCKET_LAUNCHER)
  1165.     {
  1166.         player_rocket1();
  1167.         W_FireRocket();
  1168.         self.attack_finished = time + 0.8;
  1169.     }
  1170.     else if (self.weapon == IT_LIGHTNING)
  1171.     {
  1172.         player_light1();
  1173.         self.attack_finished = time + 0.1;
  1174.         sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
  1175.     }
  1176. };
  1177.  
  1178. /*
  1179. ============
  1180. W_ChangeWeapon
  1181.  
  1182. ============
  1183. */
  1184. void() W_ChangeWeapon =
  1185. {
  1186.     local    float    it, am, fl;
  1187.     
  1188.     it = self.items;
  1189.     am = 0;
  1190.     
  1191.     if (self.impulse == 1)
  1192.     {
  1193.         fl = IT_AXE;
  1194.     }
  1195.     else if (self.impulse == 2)
  1196.     {
  1197.         fl = IT_SHOTGUN;
  1198.         if (self.ammo_shells < 1)
  1199.             am = 1;
  1200.     }
  1201.     else if (self.impulse == 3)
  1202.     {
  1203.         fl = IT_SUPER_SHOTGUN;
  1204.         if (self.ammo_shells < 2)
  1205.             am = 1;
  1206.     }        
  1207.     else if (self.impulse == 4)
  1208.     {
  1209.         fl = IT_NAILGUN;
  1210.         if (self.ammo_nails < 1)
  1211.             am = 1;
  1212.     }
  1213.     else if (self.impulse == 5)
  1214.     {
  1215.         fl = IT_SUPER_NAILGUN;
  1216.         if (self.ammo_nails < 2)
  1217.             am = 1;
  1218.     }
  1219.     else if (self.impulse == 6)
  1220.     {
  1221.         fl = IT_GRENADE_LAUNCHER;
  1222.         if (self.ammo_rockets < 1)
  1223.             am = 1;
  1224.     }
  1225.     else if (self.impulse == 7)
  1226.     {
  1227.         fl = IT_ROCKET_LAUNCHER;
  1228.         if (self.ammo_rockets < 1)
  1229.             am = 1;
  1230.     }
  1231.     else if (self.impulse == 8)
  1232.     {
  1233.         fl = IT_LIGHTNING;
  1234.         if (self.ammo_cells < 1)
  1235.             am = 1;
  1236.     }
  1237.     self.impulse = 0;
  1238.     
  1239.     if (!(self.items & fl))
  1240.     {    // don't have the weapon or the ammo
  1241.         sprint (self, "no weapon.\n");
  1242.         return;
  1243.     }
  1244.     
  1245.     if (am)
  1246.     {    // don't have the ammo
  1247.         sprint (self, "not enough ammo.\n");
  1248.         return;
  1249.     }
  1250.  
  1251. //
  1252. // set weapon, set ammo
  1253. //
  1254.     self.weapon = fl;        
  1255.     W_SetCurrentAmmo ();
  1256. };
  1257.  
  1258. /*
  1259. ============
  1260. CheatCommand
  1261. ============
  1262. */
  1263. void() CheatCommand =
  1264. {
  1265.     if (deathmatch || coop)
  1266.         return;
  1267.  
  1268.     self.ammo_rockets = 100;
  1269.     self.ammo_nails = 200;
  1270.     self.ammo_shells = 100;
  1271.     self.items = self.items | 
  1272.         IT_AXE |
  1273.         IT_SHOTGUN |
  1274.         IT_SUPER_SHOTGUN |
  1275.         IT_NAILGUN |
  1276.         IT_SUPER_NAILGUN |
  1277.         IT_GRENADE_LAUNCHER |
  1278.         IT_ROCKET_LAUNCHER |
  1279.         IT_KEY1 | IT_KEY2;
  1280.  
  1281.     self.ammo_cells = 200;
  1282.     self.items = self.items | IT_LIGHTNING;
  1283.  
  1284.     self.weapon = IT_ROCKET_LAUNCHER;
  1285.     self.impulse = 0;
  1286.         self.health = 10000;
  1287.         W_SetCurrentAmmo ();
  1288. };
  1289.  
  1290. /*
  1291. ============
  1292. CycleWeaponCommand
  1293.  
  1294. Go to the next weapon with ammo
  1295. ============
  1296. */
  1297. void() CycleWeaponCommand =
  1298. {
  1299.     local    float    it, am;
  1300.     
  1301.     it = self.items;
  1302.     self.impulse = 0;
  1303.     
  1304.     while (1)
  1305.     {
  1306.         am = 0;
  1307.  
  1308.         if (self.weapon == IT_LIGHTNING)
  1309.         {
  1310.             self.weapon = IT_AXE;
  1311.         }
  1312.         else if (self.weapon == IT_AXE)
  1313.         {
  1314.             self.weapon = IT_SHOTGUN;
  1315.             if (self.ammo_shells < 1)
  1316.                 am = 1;
  1317.         }
  1318.         else if (self.weapon == IT_SHOTGUN)
  1319.         {
  1320.             self.weapon = IT_SUPER_SHOTGUN;
  1321.             if (self.ammo_shells < 2)
  1322.                 am = 1;
  1323.         }        
  1324.         else if (self.weapon == IT_SUPER_SHOTGUN)
  1325.         {
  1326.             self.weapon = IT_NAILGUN;
  1327.             if (self.ammo_nails < 1)
  1328.                 am = 1;
  1329.         }
  1330.         else if (self.weapon == IT_NAILGUN)
  1331.         {
  1332.             self.weapon = IT_SUPER_NAILGUN;
  1333.             if (self.ammo_nails < 2)
  1334.                 am = 1;
  1335.         }
  1336.         else if (self.weapon == IT_SUPER_NAILGUN)
  1337.         {
  1338.             self.weapon = IT_GRENADE_LAUNCHER;
  1339.             if (self.ammo_rockets < 1)
  1340.                 am = 1;
  1341.         }
  1342.         else if (self.weapon == IT_GRENADE_LAUNCHER)
  1343.         {
  1344.             self.weapon = IT_ROCKET_LAUNCHER;
  1345.             if (self.ammo_rockets < 1)
  1346.                 am = 1;
  1347.         }
  1348.         else if (self.weapon == IT_ROCKET_LAUNCHER)
  1349.         {
  1350.             self.weapon = IT_LIGHTNING;
  1351.             if (self.ammo_cells < 1)
  1352.                 am = 1;
  1353.         }
  1354.     
  1355.         if ( (self.items & self.weapon) && am == 0)
  1356.         {
  1357.             W_SetCurrentAmmo ();
  1358.             return;
  1359.         }
  1360.     }
  1361.  
  1362. };
  1363.  
  1364. /*
  1365. ============
  1366. ServerflagsCommand
  1367.  
  1368. Just for development
  1369. ============
  1370. */
  1371. void() ServerflagsCommand =
  1372. {
  1373.     serverflags = serverflags * 2 + 1;
  1374. };
  1375.  
  1376. void() QuadCheat =
  1377. {
  1378.     if (deathmatch || coop)
  1379.         return;
  1380.     self.super_time = 1;
  1381.     self.super_damage_finished = time + 30;
  1382.     self.items = self.items | IT_QUAD;
  1383.     dprint ("quad cheat\n");
  1384. };
  1385.  
  1386. /*
  1387. ============
  1388. ImpulseCommands
  1389.  
  1390. ============
  1391. */
  1392. void() ImpulseCommands =
  1393. {
  1394.     if (self.impulse >= 1 && self.impulse <= 8)
  1395.         W_ChangeWeapon ();
  1396.  
  1397.     if (self.impulse == 9)
  1398.         CheatCommand ();
  1399.     if (self.impulse == 10)
  1400.         CycleWeaponCommand ();
  1401.     if (self.impulse == 11)
  1402.         ServerflagsCommand ();
  1403.         if (self.impulse == 12)
  1404.                 Flare ();
  1405.     if (self.impulse == 255)
  1406.         QuadCheat ();
  1407.         
  1408.     self.impulse = 0;
  1409. };
  1410.  
  1411. /*
  1412. ============
  1413. W_WeaponFrame
  1414.  
  1415. Called every frame so impulse events can be handled as well as possible
  1416. ============
  1417. */
  1418. void() W_WeaponFrame =
  1419. {
  1420.     if (time < self.attack_finished)
  1421.         return;
  1422.  
  1423.     ImpulseCommands ();
  1424.     
  1425. // check for attack
  1426.     if (self.button0)
  1427.     {
  1428.         SuperDamageSound ();
  1429.         W_Attack ();
  1430.     }
  1431. };
  1432.  
  1433. /*
  1434. ========
  1435. SuperDamageSound
  1436.  
  1437. Plays sound if needed
  1438. ========
  1439. */
  1440. void() SuperDamageSound =
  1441. {
  1442.     if (self.super_damage_finished > time)
  1443.     {
  1444.         if (self.super_sound < time)
  1445.         {
  1446.             self.super_sound = time + 1;
  1447.             sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
  1448.         }
  1449.     }
  1450.     return;
  1451. };
  1452.  
  1453.  
  1454. void(vector org, float spin) stuff_fly =
  1455. {
  1456.         local float xdir, ydir, zdir;
  1457.  
  1458.         xdir = 110 * random() - 55;
  1459.         ydir = 110 * random() - 55;
  1460.         zdir = 55 * random() - 25;
  1461.  
  1462.         newmis = spawn ();
  1463.         newmis.owner = self;
  1464.         newmis.movetype = MOVETYPE_BOUNCE;
  1465.         newmis.solid = SOLID_BBOX;
  1466.         newmis.touch = GrenadeTouch; //T_MissileTouch;
  1467.         newmis.think = BigBoom; //SUB_Remove;
  1468.         newmis.nextthink = time + 1.0;
  1469.         newmis.velocity_x = xdir * 5; 
  1470.         newmis.velocity_y = ydir * 5;
  1471.         newmis.velocity_z = zdir * 4;
  1472.         setmodel (newmis, "progs/missile.mdl");
  1473.         setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
  1474.         setorigin (newmis, org);
  1475.         
  1476.     if (spin == 0)
  1477.     newmis.avelocity='250 300 400';
  1478.     if (spin == 1)
  1479.     newmis.avelocity='400 250 300';
  1480.     if (spin == 2)
  1481.     newmis.avelocity='300 400 250';
  1482.     if (spin == 3)
  1483.     newmis.avelocity='300 300 300';
  1484.     if (spin == 4) 
  1485.     newmis.avelocity='400 250 400';
  1486.         
  1487.  
  1488. };
  1489.